home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 30
/
Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso
/
Aminet
/
util
/
pack
/
xpk_Source.lha
/
xpk_Source
/
libraries
/
DUKE
/
xpkDUKE.c
next >
Wrap
C/C++ Source or Header
|
1998-11-09
|
6KB
|
264 lines
/*
* This library is mainly intended to demonstrate how to program a sub
* library.
*/
#define VERSION 1
#include <xpk/xpksub.h>
#include <exec/memory.h>
#include <proto/exec.h>
#define SDI_TO_ANSI
#include "SDI_ASM_STD_protos.h"
#ifdef __MAXON__
#define __asm
#endif
#define SysBase (*((struct ExecBase **) 4));
#define SCANBUFLEN 32768
/*
* Pack a chunk
*/
struct NukeData {
APTR inbuf;
APTR outbuf;
APTR last;
APTR next;
ULONG cwri;
ULONG uwri;
ULONG uend;
ULONG delpos;
UWORD ulen;
UWORD clen;
UWORD ustop;
UWORD ustart;
UWORD ucount;
UWORD scanrange;
UWORD room1;
UWORD room2;
UWORD room4;
UWORD roomN;
UWORD data1;
UWORD data2;
ULONG data4;
ULONG dataN;
ULONG dest1;
ULONG dest2;
ULONG dest4;
ULONG destN;
ULONG dummy;
ULONG contbuf;
ULONG flags;
};
#ifdef __cplusplus
extern "C" {
#endif
LONG __asm AsmPack (register __a4 struct NukeData *ND);
STRPTR __asm AsmUnpack(register __a1 STRPTR wread, register __a4 STRPTR bread,
register __a0 STRPTR dst, register __a2 STRPTR end);
#ifdef __cplusplus
}
#endif
#define PACKMEM (65536+SCANBUFLEN)*sizeof(UWORD)+sizeof(struct NukeData)+SCANBUFLEN
#define UNPACKMEM SCANBUFLEN
#define A3000 XPKMF_A3000SPEED
static struct XpkMode DukeMode = {
NULL, // Next mode
100, // Handles up to
A3000, // Flags
PACKMEM, // Packing memory
UNPACKMEM, // Unpacking memory
36, // Packing speed
630, // Unpacking speed
454, // Compression ratio
0, // Reserved
"normal", // Description
};
static struct XpkInfo DukeInfo = {
1, /* info version */
VERSION, /* lib version */
0, /* master vers */
1, /* ModesVersion */
(STRPTR) "DUKE", /* short name */
(STRPTR) "Duke", /* long name */
(STRPTR) "NUKE with a delta preprocessor", /* Description */
0x44554B45, /* 'DUKE', 4 letter ID */
XPKIF_PK_CHUNK | /* flags */
XPKIF_UP_CHUNK,
30000, /* max in chunk */
10, /* min in chunk */
30000, /* def in chunk */
(STRPTR) "Duking", /* pk message */
(STRPTR) "Unduking", /* up message */
(STRPTR) "Duked", /* pk past msg */
(STRPTR) "Unduked", /* up past msg */
50, /* DefMode */
0, /* Pad */
&DukeMode, /* ModeDesc */
0, /* MinModeDesc */
0, /* MaxModeDesc */
0,0,0,0 /* reserved */
};
void DoDelta(STRPTR dst, STRPTR src, LONG len)
{
UBYTE a=0, b=0;
if (len>0) {
switch (len & 7) {
do {
case 0: *dst++ = (UBYTE) ((b=*src++) - a);
case 7: *dst++ = (UBYTE) ((a=*src++) - b);
case 6: *dst++ = (UBYTE) ((b=*src++) - a);
case 5: *dst++ = (UBYTE) ((a=*src++) - b);
case 4: *dst++ = (UBYTE) ((b=*src++) - a);
case 3: *dst++ = (UBYTE) ((a=*src++) - b);
case 2: *dst++ = (UBYTE) ((b=*src++) - a);
case 1: *dst++ = (UBYTE) ((a=*src++) - b);
} while ((len-=8)>0);
}
}
}
void UndoDelta(STRPTR dst, STRPTR src, LONG len)
{
UBYTE l = 0;
if (len > 0) {
switch (len & 7) {
do {
case 0: *dst++ = (l+=*src++);
case 7: *dst++ = (l+=*src++);
case 6: *dst++ = (l+=*src++);
case 5: *dst++ = (l+=*src++);
case 4: *dst++ = (l+=*src++);
case 3: *dst++ = (l+=*src++);
case 2: *dst++ = (l+=*src++);
case 1: *dst++ = (l+=*src++);
} while ((len-=8)>0);
}
}
}
/*
* Returns an info structure about our packer
*/
#ifdef __cplusplus
extern "C"
#endif
struct XpkInfo *XpksPackerInfo(void)
{
return &DukeInfo;
}
#ifdef __cplusplus
extern "C"
#endif
#define LASTSIZE (65536*sizeof(UWORD))
#define NEXTSIZE (SCANBUFLEN*sizeof(UWORD))
void __asm XpksPackFree(register __a0 struct XpkSubParams *xpar)
{
struct NukeData *ND = (struct NukeData *) xpar->xsp_Sub[0];
if(xpar->xsp_Sub[1])
{
FreeMem((APTR) xpar->xsp_Sub[1], SCANBUFLEN);
xpar->xsp_Sub[1] = 0;
}
if(ND)
{
if(ND->last) FreeMem(ND->last, LASTSIZE);
if(ND->next) FreeMem(ND->next, NEXTSIZE);
FreeMem(ND, sizeof(struct NukeData));
xpar->xsp_Sub[0] = 0;
}
}
struct NukeData *alloctabs(struct XpkSubParams *xpar)
{
struct NukeData *ND;
if ((xpar->xsp_Sub[0] = (LONG) (ND = (struct NukeData*) AllocMem(sizeof(struct NukeData),MEMF_CLEAR))) &&
(ND->last = AllocMem(LASTSIZE,0)) &&
(ND->next = AllocMem(NEXTSIZE,0)) &&
(xpar->xsp_Sub[1] = (LONG) AllocMem(SCANBUFLEN,0))) {
return ND;
}
else
{
XpksPackFree(xpar);
return 0;
}
}
#ifdef __cplusplus
extern "C"
#endif
LONG __asm XpksPackChunk(register __a0 struct XpkSubParams *xpar )
{
struct NukeData *ND=(struct NukeData *)xpar->xsp_Sub[0];
if (!ND)
if (!(ND=alloctabs(xpar)))
return XPKERR_NOMEM;
DoDelta((STRPTR)xpar->xsp_Sub[1], (STRPTR) xpar->xsp_InBuf, xpar->xsp_InLen);
ND->inbuf = (APTR) xpar->xsp_Sub[1];
ND->outbuf= xpar->xsp_OutBuf;
ND->ulen = (UWORD) xpar->xsp_InLen;
ND->clen = (UWORD) (xpar->xsp_OutBufLen-4);
memset(ND->last,0,LASTSIZE);
memset(ND->next,0,NEXTSIZE);
if(((LONG)(xpar->xsp_OutLen = AsmPack(ND))) <0 || xpar->xsp_OutLen>xpar->xsp_InLen)
{
/* XpksPackReset(xpar); ist empty function */
return XPKERR_EXPANSION;
}
return 0;
}
#ifdef __cplusplus
extern "C"
#endif
LONG __asm XpksUnpackChunk(register __a0 struct XpkSubParams *xpar)
{
if(!xpar->xsp_Sub[1] && !(xpar->xsp_Sub[1] = (LONG) AllocMem(SCANBUFLEN,0)))
return XPKERR_NOMEM;
AsmUnpack((STRPTR) xpar->xsp_InBuf, (STRPTR)xpar->xsp_InBuf + xpar->xsp_InLen,
(STRPTR)xpar->xsp_Sub[1], (STRPTR)xpar->xsp_Sub[1] + xpar->xsp_OutLen);
UndoDelta((STRPTR)xpar->xsp_OutBuf, (STRPTR )xpar->xsp_Sub[1], xpar->xsp_OutLen);
return 0;
}
#ifdef __cplusplus
extern "C"
#endif
void __asm XpksUnpackFree(register __a0 struct XpkSubParams *xpar)
{
if (xpar->xsp_Sub[1]) FreeMem((APTR)xpar->xsp_Sub[1], SCANBUFLEN), xpar->xsp_Sub[1]=0;
}